home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
bccmouse.zip
/
MOUSE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-10
|
9KB
|
490 lines
/**********************************************************************
*
* NAME: mouse.cpp
*
* DESCRIPTION: mouse interface
*
* M O D I F I C A T I O N H I S T O R Y
*
* when who what
* -------------------------------------------------------------------
* 12/18/90 J. Alan Eldridge created
*
* NOTES: this was created using TC++ v. 1.90 beta:
* "eventhandler()" will not compile correctly under TC++ 1.00
*
*********************************************************************/
#include <dos.h>
#include <time.h>
#include "mouse.h"
#define TRUE 1
#define FALSE 0
#define MOUSEINTR 0x33
static int installed = FALSE;
static int oldmask;
void cdecl huge _saveregs (*oldhandler)();
static int nbuttons,
eventmask,
qsize;
#define NEVENT 8
static int evhead = 0, evtail = 0, evcount = 0;
static MouEvent mouEvent[NEVENT];
volatile int far *mou_pkbshift = (volatile int far *)MK_FP(0x40, 0x17);
static int (*userfunc)(MouEvent&);
static int usermask;
inline int topixels(int rowcol)
{ return rowcol * 8; }
inline int torowcol(int pixels)
{ return pixels / 8; }
int
mou_exists()
{
return installed;
}
int
mou_buttons()
{
return nbuttons;
}
int
mou_resetmouse()
{
_AX = 0;
geninterrupt(MOUSEINTR);
if (_AX)
_AX = _BX;
return _AX;
}
void
mou_showptr()
{
_AX = 1;
geninterrupt(MOUSEINTR);
}
void
mou_hideptr()
{
_AX = 2;
geninterrupt(MOUSEINTR);
}
static int
buttonstatus(int &vref, int &href)
{
int buttons;
_AX = 3;
geninterrupt(MOUSEINTR);
buttons = _BX;
vref = _DX;
href = _CX;
return buttons;
}
static void
setposition(int v, int h)
{
_AX = 4;
_CX = h;
_DX = v;
geninterrupt(MOUSEINTR);
}
static int
press_release(int func, int &cntr, int &v, int &h)
{
_AX = func;
geninterrupt(MOUSEINTR);
int count = _BX;
int button = _AX;
cntr = count;
v = _DX;
h = _CX;
return button;
}
static int
buttonpress(int &cntr, int &v, int &h)
{
return press_release(0x5, cntr, v, h);
}
static int
buttonrelease(int &cntr, int &v, int &h)
{
return press_release(0x6, cntr, v, h);
}
static void
setlims(int func, int minval, int maxval)
{
_AX = func;
_CX = minval;
_DX = maxval;
geninterrupt(MOUSEINTR);
}
static void
sethlimits(int minval, int maxval)
{
setlims(0x7, minval, maxval);
}
static void
setvlimits(int minval, int maxval)
{
setlims(0x8, minval, maxval);
}
static void
settxtptr(int type, int arg1, int arg2)
{
_AX = 0xA;
_BX = type;
_CX = arg1;
_DX = arg2;
geninterrupt(MOUSEINTR);
}
void
mou_setsoftptr(int andmask, int xormask)
{
settxtptr(0, andmask, xormask);
}
void
mou_sethardptr(int start, int end)
{
settxtptr(1, start, end);
}
static void
_seteventhandler(int mask, int hoff, int hseg)
{
_CX = mask;
_DX = hoff;
_ES = hseg;
_AX = 0xC;
geninterrupt(MOUSEINTR);
}
void
mou_seteventhandler(int mask, void huge cdecl _saveregs (*handler)())
{
_seteventhandler(mask, FP_OFF(handler), FP_SEG(handler));
}
static void
setexclusionarea(int yul, int xul, int ylr, int xlr)
{
_AX = 0x10;
_DX = yul;
_CX = xul;
_DI = ylr;
_SI = xlr;
geninterrupt(MOUSEINTR);
}
static int
_swapeventhandler(int mask, int newoff, int newseg, int &oldoff, int &oldseg)
{
int off, seg, omask;
_DX = newoff;
_ES = newseg;
_CX = mask;
_AX = 0x14;
geninterrupt(MOUSEINTR);
omask = _CX;
off = _DX;
seg = _ES;
oldoff = off;
oldseg = seg;
return omask;
}
int
mou_swapeventhandler(int mask,
void cdecl huge _saveregs (*newhandler)(),
void cdecl huge _saveregs (**oldhandler)())
{
int omask, off, seg;
omask = _swapeventhandler(mask, FP_OFF(newhandler),
FP_SEG(newhandler), off, seg);
*oldhandler = (void (far *)())(MK_FP(seg, off));
return omask;
}
int
mou_savestatesize()
{
_AX = 0x15;
geninterrupt(MOUSEINTR);
return _BX;
}
static void
statemanip(int func, unsigned char far *buf)
{
_DX = FP_OFF(buf);
_ES = FP_SEG(buf);
_AX = func;
geninterrupt(MOUSEINTR);
}
void
mou_savestate(unsigned char *buf)
{
statemanip(0x16, buf);
}
void
mou_restorestate(unsigned char *buf)
{
statemanip(0x17, buf);
}
int
mou_resetdriver()
{
_AX = 0x21;
geninterrupt(MOUSEINTR);
if (_AX == 0xFFFF)
return _BX;
return 0;
}
void interrupt
(*mou_disabledriver())()
{
int oldseg, oldoff;
_AX = 0x1F;
geninterrupt(MOUSEINTR);
if (_AX == 0x1F) {
oldoff = _BX;
oldseg = _ES;
} else {
oldoff = oldseg = 0;
}
return (void interrupt (*)())(MK_FP(oldseg,oldoff));
}
int
mou_buttonstatus(int &v, int &h)
{
int button = buttonstatus(v, h);
v = torowcol(v);
h = torowcol(h);
return button;
}
int
mou_buttonpress(int &n, int &v, int &h)
{
int button = buttonpress(n, v, h);
v = torowcol(v);
h = torowcol(h);
return button;
}
int
mou_buttonrelease(int &n, int &v, int &h)
{
int button = buttonrelease(n, v, h);
v = torowcol(v);
h = torowcol(h);
return button;
}
void
mou_sethlimits(int minval, int maxval)
{
sethlimits(topixels(minval), topixels(maxval+1)-1);
}
void
mou_setvlimits(int minval, int maxval)
{
setvlimits(topixels(minval), topixels(maxval+1)-1);
}
void
mou_setposition(int v, int h)
{
setposition(topixels(v), topixels(h));
}
void
mou_setexclusionarea(int yul, int xul, int ylr, int xlr)
{
setexclusionarea(topixels(yul), topixels(xul),
topixels(ylr+1)-1, topixels(xlr+1)-1);
}
// this is the event function called by the mouse driver ...
// begin_flame {
// as originally written, it would NOT compile correctly under
// TC++ 1.00: the return address on the stack gets munged by an
// extra instruction the compiler inserts before it starts the
// great register pop (specifically, the contents of AX blows away
// the saved IP, and you return to some place on the dark side
// of the moon). the version checking code inserted here forces
// AX to the right value before coming back, thus patching the
// compiler's error. Note that TC++ 1.00 returns version 0x0295,
// while TC++ 1.90 beta returns version 0x0297 (drugs, maybe???).
// } end_flame
static void cdecl huge _saveregs
eventhandler()
{
int e = _AX, b = _BX,
v = _DX, h = _CX;
#if __TURBOC__ < 0x0297
int saveip = ((int _ss *)_BP)[10];
#endif
if (e & usermask) {
mouEvent[evhead].kbshift = *mou_pkbshift;
mouEvent[evhead].ticks = clock();
mouEvent[evhead].event = e;
mouEvent[evhead].buttons = b;
mouEvent[evhead].vertpos = torowcol(v);
mouEvent[evhead].horzpos = torowcol(h);
if (!userfunc || userfunc(mouEvent[evhead])) {
if (evcount < qsize)
evcount++;
else if (++evtail == qsize)
evtail = 0;
if (++evhead == qsize)
evhead = 0;
}
}
#if __TURBOC__ < 0x0297
_AX = saveip;
#endif
}
class mouse {
private:
int exists;
public:
mouse();
~mouse();
};
static mouse Mouse;
mouse::mouse()
{
evhead = evtail = evcount = 0;
exists = (nbuttons = mou_resetmouse()) != 0;
if (exists && !installed) {
oldmask = mou_swapeventhandler(eventmask = 0,
eventhandler, &oldhandler);
usermask = MouEvAllEvents;
userfunc = 0;
qsize = NEVENT;
installed = TRUE;
mou_setsoftptr();
}
}
mouse::~mouse()
{
if (installed) {
mou_seteventhandler(oldmask, oldhandler);
mou_resetmouse();
installed = FALSE;
}
}
int
mou_seteventmask(int newmask)
{
int savemask = eventmask;
evhead = evtail = evcount = 0;
mou_seteventhandler(eventmask = newmask, eventhandler);
return savemask;
}
int
mou_getevent(MouEvent &ev)
{
int savecnt;
disable();
if (savecnt = evcount) {
ev = mouEvent[evtail];
if (++evtail == qsize) evtail = 0;
evcount--;
}
enable();
return savecnt;
}
void
mou_flushevents()
{
disable();
evhead = evtail = evcount = 0;
enable();
}
void
mou_setuserfunc(int (*userfunc)(MouEvent &))
{
disable();
::userfunc = userfunc;
enable();
}
int
mou_setusermask(int newmask)
{
int savemask = usermask;
disable();
usermask = newmask;
enable();
return savemask;
}
int
mou_seteventqsize(int newsize)
{
int savesize = qsize;
if (newsize < 1 || newsize > NEVENT)
newsize = NEVENT;
disable();
evhead = evtail = evcount = 0;
qsize = newsize;
enable();
return savesize;
}